<template>
  <section class="wan-e-editor" :style="editorStyle">
    <div ref="toolbarRef" class="wan-e-toolbar" :style="toolbarStyle"></div>
    <div ref="contentRef" class="wan-e-content" :style="{height:height}"></div>
    <textarea readonly :id="'form_item_'+name" :name="name" :value="value" style="display: none"/>
  </section>
</template>

<script setup lang="ts">
import {createEditor, createToolbar, type IDomEditor, type IEditorConfig, type IToolbarConfig} from '@wangeditor/editor'
import {computed, onBeforeUnmount, onMounted, type PropType, reactive, ref, shallowRef, watch} from "vue";
import {toolbarKeys,simpleToolbarKeys} from "@/config/editorConfig.ts";
import "@/assets/wang-editor.css"

import useMessage from "@/hooks/useMessage.ts";
import type { EditorModel, UploadResponse } from '@/types/editor';
import { baseURL } from '@/config';

const toolbarRef = ref(null)
const contentRef = ref(null)
let editorRef = shallowRef<IDomEditor | undefined>(undefined)

const value = defineModel<string>('value')

const props = defineProps({
  //  编辑器模式 默认为default，可选值：default | simple
  model:{type: String as  PropType<EditorModel>,default:'default'},
  //  是否显示边框
  bordered:{type: Boolean,default:true},
  //  内容区域高度
  height:{type: String,default:'200px'},
  maxHeight:{type: String,default:''},
  //  上传服务器地址
  server:{type: String,default:''},
  //  上传文件字段名o 上传文件字段名o、、、、、
  fileName:{type: String,default:'file'},
  //  上传文件大小限制，默认2M
  fileSize:{type: Number,default:1024 * 1024 * 5},
  //  上传文件数量限制，默认5
  fileMax:{type: Number,default:5},
  //  placeholder
  placeholder:{type: String,default:'请输入内容...'},
  //  token
  token:{type: String,default:''},
  //  背景颜色 默认#fafafa
  bgColor:{type: String,default:'#fafafa'},
  //  边框颜色 默认#d9d9d9
  borderColor:{type: String,default:'#d9d9d9'},
  //  圆角 默认6px
  borderRadius:{type: String,default:'6px'},
  //用于表单数据验证
  name:{type:String,default:'textarea'}
})
const editorStyle = reactive<{[key:string]:string}>({
  borderRadius: props.borderRadius || '6px',
  borderColor: props.bordered ? props.borderColor : 'transparent',
  background: props.bordered  ? '#fff' : props.bgColor,
  boxShadow: '',
})
//工具栏样式
const toolbarStyle = computed<Record<string, string>>(()=>{
  return {
    borderColor: props.bordered ? props.borderColor : '#f0f0f0',
    margin:  props.bordered ? '0' : '0 5px',
  }
})
//工具栏配置
const toolbarConfig:Partial<IToolbarConfig> = {
  toolbarKeys: props.model === 'simple' ? simpleToolbarKeys : toolbarKeys
}
/**
 * 编辑配置
 *
 */
const  editorConfig:Partial<IEditorConfig> = {
  placeholder: props.placeholder,
  customAlert: (info:string, type:any) => {
    let code:number =100
    switch ( type){
      case 'error':
       code = 500
        break
      case 'success':
        code = 200
        break
      case 'warning':
        code = 400
        break
      case 'info':
        code = 100
        break
    }
    useMessage(code, info)
  },
  MENU_CONF: {
    uploadImage:{
      server: baseURL+'/api/uploader',
      fieldName: props.fileName,
      maxNumber: props.fileMax,
      maxFileSize: props.fileSize,
      customInsert: (res:UploadResponse, insertImgFn:Function) => {
        //服务器返回的图片地址
        const url = baseURL+res.data.file_url
        //插入图片
        insertImgFn(url, '')
      },
      meta:{
        token:props.token
      }
    },
    uploadVideo:{
      server: baseURL+'api/uploader',
      fieldName: props.fileName,
      maxNumber: props.fileMax,
      maxFileSize: props.fileSize,
      customInsert: (res:UploadResponse, insertVideoFn:Function) => {
        //服务器返回的视频地址
        const url = res.data
        //插入视频
        insertVideoFn(url, '')
      },
      meta:{
        token:props.token
      }
    }
  }
}

const initEditor = ()=>{
  //如果内容区域为空，则返回
  if (!contentRef.value) return
  console.warn = () => {}
  //创建编辑器实例
  editorRef.value = createEditor({
    selector: contentRef.value! as HTMLElement,
    mode: props.model,
    html:  value.value || '',
    config: {
      ...editorConfig,
      onCreated: (editor:IDomEditor) => {
        //创建编辑器实例成功
        editorRef.value = editor
        
      },
      onChange: (editor:IDomEditor) => {
        //实时更新内容
        value.value = editor.getHtml()
      },
      onDestroyed: () => {
        //销毁编辑器实例
        editorRef.value = undefined
      },
      onFocus: () => {
        editorStyle.borderColor='#4096ff'
        editorStyle.boxShadow = '0 2px 8px rgba(0,0,0,0.05)'
      },
      onBlur: (editor: IDomEditor) => {
        editorStyle.borderColor= props.bordered ? props.borderColor : 'transparent'
        editorStyle.boxShadow = ''
        value.value = editor.getHtml()
      }
    },
  })
  //创建工具栏实例
  createToolbar({
    editor:editorRef.value,
    mode: props.model,
    selector: toolbarRef.value! as HTMLElement,
    config: toolbarConfig
  })
}
watch(()=>value.value,(val)=>{
  editorRef.value?.setHtml(val ?? '')
})
onMounted(()=>{
  initEditor()
})
onBeforeUnmount(()=>{
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
</script>

<style scoped>
</style>